package com.rp.log.aop;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.rp.common.utils.RpUtil;
import com.rp.log.annotation.RpLog;
import com.rp.system.po.SysLog;
import com.rp.system.po.User;
import com.rp.system.service.SysLogService;

@Aspect
@Component
@Order(value=1)
public class LogAspect {
	
	@Autowired
	private SysLogService sysLogService;
	
	/**
	 * 标注该方法体为后置通知，当目标方法执行成功后执行该方法体  
	 * @param jp
	 * @param rl
	 */
	@AfterReturning("within(com..*.service..*) && @annotation(rl)")
	public void afterLog(JoinPoint jp, RpLog rl){
		Object[] params = jp.getArgs();//获取目标方法体参数
		String paramsResult = parseParams(params);//解析 目标方法体的参数
		String className = jp.getTarget().getClass().toString();//获取目标类名   
        className = className.substring(className.indexOf("com"));   
        String signature = jp.getSignature().toString();//获取目标方法签名 
        String methodName = signature.substring(signature.lastIndexOf(".")+1, signature.indexOf("("));      
        
        //获取当前登录用户
        User loginUser = User.getCurrentUser();
        
        SysLog sl = new SysLog();
        sl.setCreateDate(RpUtil.getCurrentDatetime());
        sl.setClassName(className);
        sl.setMethodName(methodName);
        sl.setParams(paramsResult);
        sl.setDescription(rl.desc());
        sl.setOperResult("成功");
        if(!RpUtil.isNullOrEmpty(loginUser)){
        	sl.setExecutorName(loginUser.getRealname());
        }
        
        sysLogService.saveSysLog(sl);
        
        //String ip = (String)ActionContext.getContext().getSession().get(""); //用户IP  
	}
	
	/**
	 * 标注该方法体为异常通知，当目标方法出现异常时，执行该方法体
	 * @param jp 
	 * @param rl 
	 * @param ex 对应注解中throwing="ex"中的ex
	 */
    @AfterThrowing(value="within(com..*.service..*) && @annotation(rl)", throwing="ex")
    public void exceptionLog(JoinPoint jp, RpLog rl, Exception ex){
    	Object[] params = jp.getArgs();
        String paramsResult = parseParams(params);
        String className = jp.getTarget().getClass().toString();
        className = className.substring(className.indexOf("com"));
        String signature = jp.getSignature().toString();
        String methodName = signature.substring(signature.lastIndexOf(".")+1, signature.indexOf("("));
        
        //获取当前登录用户
        User loginUser = User.getCurrentUser();
        
        SysLog sl = new SysLog();
        sl.setCreateDate(RpUtil.getCurrentDatetime());
        sl.setClassName(className);
        sl.setMethodName(methodName);
        sl.setParams(paramsResult);
        sl.setDescription(rl.desc());
        sl.setOperResult("失败");
        if(!RpUtil.isNullOrEmpty(loginUser)){
        	sl.setExecutorName(loginUser.getRealname());
        }
        sl.setExceptionMsg(ex.toString());
        
        sysLogService.saveSysLog(sl);
    }
    
    /**
     * 解析参数
     * @param params
     * @return
     */
    public String parseParams(Object[] params){
    	List<Object> list = new ArrayList<Object>();
    	for(int i=0; i<params.length; i++){
    		if(params[i] != null){
    			list.add(params[i]);
    		}
    	}
    	JSONArray json = JSONArray.fromObject(list);
    	return json.toString();
    }
	
}
